(function ($) {
  "use strict";
  $.fn.calendar = function (option) {
    var self = $(this);
    option = $.extend({},option);
    self.on("click", function () {
      option.self = self;
      option.curDate = self.data("date");
      option.startDate = self.data("start");
      option.endDate = self.data("end");
      $.calendar(option)
    });
  };
  $.calendar = function (option) {
    var defaults = {
      type: 'picked',
      self: $(".gzl-calendar-item"), // 当前显示目标父元素
      calendar: null, // 当前日历
      items: null, // 渲染日历个数
      tag: {'cu': '促','jian': '减','qiang': '抢'},
      nav: null, // 日历导航
      date: {
        // '2018-12-28': {
        //   holiday: '节日',
        //   tag: 'qiang',
        //   price: parseInt(Math.random()*10000),
        //   num: 0
        // }
      },
      isFull: true, // false的时候只date{}里的日期可选
      curDate: '', // 当前日期
      curTarget: 'cur', // 当前日期的显示目标
      range: false, // 是否范围选择
      maxRange: null, // 最大可选范围
      startDate: null, // 范围开始日期
      endDate: null, // 范围结束日期
      startTarget: "start", // 范围开始的显示目标
      endTarget: "end", // 范围结束的显示目标
      startStr: '入住',
      endStr: '离店',
      gridClick: function () {}
    };
    var params = $.extend({},defaults,option);
    var today = new Date();
    var calendar = {
      init: function () {
        var next_month, month_list, tpl;
        var monthArr = [];
        var firstMonth = params.nav && Object.keys(params.nav)[0]?new Date(Object.keys(params.nav)[0]):today;
        monthArr.push(firstMonth);
        if (!params.items){
          params.items = params.type === 'picked'?4:1;
        }
        if(params.items>1){
          for(var i=1;i<params.items;i++){
            next_month = new Date(firstMonth.getFullYear(), firstMonth.getMonth() + i, 1);
            monthArr.push(next_month)
          }
        }
        month_list = calendar.getMonthDay(monthArr); // 获取显示月份
        tpl = '<div class="gzl-calendar '+(params.type === "picked"?'gzl-calendar_popup':'')+'"><div class="gzl-calendar__week"></div><div class="gzl-calendar__group"></div></div></div>';
        params.calendar = $(tpl).appendTo(params.type==="picked"?document.body:params.self);
        var nav_tpl = '';// 月份导航显示
        var week_tpl = '';// 周显示
        var week = ['日','一','二','三','四','五','六'];
        if (params.nav) {
          for (var i in params.nav) {
            nav_tpl += '<li data-date="'+i+'"><strong>'+ (new Date(i).getMonth() + 1) +'月</strong><p>￥'+ params.nav[i] +'</p></li>';
          }
          params.calendar.find(".gzl-calendar__week").before("<div class='gzl-calendar__nav'><ul></ul></div>");
          var navDom = params.calendar.find(".gzl-calendar__nav ul");
          navDom.append(nav_tpl);
          if (navDom.find("li").length > 5){
            navDom.addClass("auto");
          }
          navDom.find("li").first().addClass("active");
        }else if(params.type !== 'picked') {
          var top = $('<div class="gzl-calendar__top"></div>').prependTo(params.calendar);
          top.before('<span class="prev-btn">左</span><span class="next-btn">右</span>');
        }
        for (var i=0;i<week.length;i++){
          week_tpl += '<span>'+ week[i] +'</span>';
        }
        params.calendar.find(".gzl-calendar__week").append(week_tpl);
        calendar.baseCalendar(month_list); // 日历界面初始化
        calendar.initEvent();
        if (params.type === "picked") {
          params.calendar.show().addClass("show");
        }
      },
      initEvent: function () {
        calendar.navClick();// 月份导航点击
        calendar.groupEvent();// 日格子点击
        calendar.prevClick();
        calendar.nextClick();
      },
      getMonthDay: function (months) {// 获取月份渲染内容
        var all_months = [];
        for (var i = 0; i < months.length; i++) {// 遍历月
          var month_days = [];
          var date_num = getMonthDateNumber(months[i]);// 获取一个月的天数
          var firstDay = new Date(months[i].getFullYear(), months[i].getMonth(), 1);
          for (var j=0;j<date_num+firstDay.getDay();j++){// 遍历天
            var tem_date;
            var curMonth = true;
            if (j < firstDay.getDay()) { // 小于今日
              tem_date = new Date(firstDay.getTime() - (firstDay.getDay() - j) * 24 * 60 * 60 * 1000);
              curMonth = false;
            } else if (j >= firstDay.getDay() && j < firstDay.getDay() + date_num) { // 当月
              tem_date = new Date(months[i].getFullYear(), months[i].getMonth(), (j-firstDay.getDay()) + 1);
              curMonth = true;
            } else { // 下个月
              tem_date = new Date(firstDay.getTime() + (j-firstDay.getDay()) * 24 * 60 * 60 * 1000);
              curMonth = false;
            }
            var todayDate = today.getFullYear() + "-" + dbDate(today.getMonth() + 1)  + "-" + dbDate(today.getDate());
            var fullyear = tem_date.getFullYear() + "-" + dbDate(tem_date.getMonth() + 1) + "-" + dbDate(tem_date.getDate());
            var holiday = null; // 节假日
            var tag = null; // 活动
            var price = null; // 价格
            var num = null; // 数量
            var disable = true;
            if(params.date[fullyear]){
              if (new Date(fullyear)>today) {
                tag = params.date[fullyear].tag;
                price = params.date[fullyear].price;
              }
              holiday = params.date[fullyear].holiday;
              num = params.date[fullyear].num;
            }
            if (params.isFull) {
              disable = new Date(fullyear) < new Date(todayDate);
            } else {
              disable = !params.date[fullyear] || new Date(fullyear) < new Date(todayDate) || false;
            }
            month_days.push({
              date: fullyear,
              year: tem_date.getFullYear(),
              month: tem_date.getMonth() + 1,
              day: tem_date.getDate(),
              week: tem_date.getDay(),
              curMonth: curMonth,
              disable: disable,
              active: params.curDate === fullyear,
              startDate: params.startDate === fullyear,
              endDate: params.endDate === fullyear,
              range: new Date(fullyear) > new Date(params.startDate) && new Date(fullyear) < new Date(params.endDate),
              holiday: holiday,
              tag: tag,
              price: price,
              num: num
            })
          }
          all_months.push(month_days);
        }
        return all_months;
      },
      baseCalendar: function (monthList) {// 渲染日历
        // console.log(monthList);
        var date_tpl = '';// 日显示
        if ($(".gzl-calendar__top", params.calendar).length>0){
          $(".gzl-calendar__top", params.calendar).text(monthList[0][6].year + '年' + monthList[0][6].month + '月');
        }
        for (var i=0;i<monthList.length;i++) {
          var year = monthList[i][6].year;
          var month = monthList[i][6].month;
          var ym = year + "年" + month + "月";
          var first_day = monthList[i][0].week;
          date_tpl += '<div class="gzl-calendar__item" data-year="'+year+'" data-month="'+month+'">'+
            (params.type==='picked'?'<div class="gzl-calendar__tit"><strong>'+ym+'</strong></div>':'') +
            '<div class="gzl-calendar__daylist">';
          for(var j=0;j<monthList[i].length+first_day;j++){
            var dateblank = '';
            if(monthList[i][j].curMonth){
              dateblank = '<div class="gzl-calendar__grid'+
                (monthList[i][j].active?' active':'') +
                (monthList[i][j].startDate?' start-date':'') +
                (monthList[i][j].endDate?' end-date':'') +
                (monthList[i][j].range?' range-item':'') +
                (monthList[i][j].disable || monthList[i][j].num === 0?' disable':'')+
                '"'+
                ' data-date="'+monthList[i][j].date+'">'+
                '<div class="gzl-calendar__hd'+(monthList[i][j].tag?' gzl-calendar__'+monthList[i][j].tag:'')+'">' +
                  (monthList[i][j].holiday?'<span class="gzl-calendar__holiday">'+monthList[i][j].holiday+'</span>':'')+
                  (monthList[i][j].tag?'<span class="gzl-calendar__tag">'+params.tag[monthList[i][j].tag]+'</span>':'') +
                '</div>' +
                '<div class="gzl-calendar__day">'+monthList[i][j].day+'</div>'+
                '<div class="gzl-calendar__ft">' +
                  (monthList[i][j].price && monthList[i][j].num !== 0?'<span class="gzl-calendar__price">￥'+monthList[i][j].price+'</span>':'') +
                  (monthList[i][j].num === 0 && monthList[i][j].date >= today?'<span>售罄</span>':'') +
                  (monthList[i][j].startDate?'<span class="range-tip">'+params.startStr+'</span>':'') +
                  (monthList[i][j].endDate?'<span class="range-tip">'+params.endStr+'</span>':'') +
                '</div>' +
                '</div>';
            }
            date_tpl += '<span class="gzl-calendar__blank">'+dateblank+'</span>';
          }
          date_tpl += '</div></div></div>';
        }
        params.calendar.find(".gzl-calendar__group").html("").append(date_tpl);
      },
      prevClick: function () {// 左点击
        $(".prev-btn", params.calendar).on("click", function () {
          var month_list;
          var all_month = [];
          params.calendar.find(".gzl-calendar__item").each(function () {
            var prev_month = new Date(parseInt($(this).data("year")), parseInt($(this).data("month")) - 2, 1);
            month_list = calendar.getMonthDay([prev_month]);
            all_month.push(month_list[0]);
          });
          calendar.baseCalendar(all_month);
          calendar.groupEvent();
        })
      },
      nextClick: function () {// 右点击
        $(".next-btn", params.calendar).on("click", function () {
          var month_list;
          var all_month = [];
          params.calendar.find(".gzl-calendar__item").each(function () {
            var next_month = new Date(parseInt($(this).data("year")), parseInt($(this).data("month")), 1);
            month_list = calendar.getMonthDay([next_month]);
            all_month.push(month_list[0]);
          });
          calendar.baseCalendar(all_month);
          calendar.groupEvent();
        })
      },
      navClick: function () {// 月份导航点击
        var nav = params.calendar.find(".gzl-calendar__nav");
        $("li", nav).on("click", function () {
          $(this).addClass("active").siblings().removeClass("active");
          calendar.baseCalendar(calendar.getMonthDay([new Date($(this).data("date"))]));
          calendar.groupEvent();
        })
      },
      groupEvent: function () {// 日历点击事件
        var grid = params.calendar.find(".gzl-calendar__grid");
        grid.on("click", function () {
          if(!$(this).hasClass("disable")){
            var date = $(this).data("date");
            if (!params.range) {
              grid.removeClass("active");
              $(this).addClass("active");
              params.self.data("date", date).removeClass("placeholder").find("[data-target="+params.curTarget+"]").text(date);
              params.gridClick(date, params.self);
              calendar.hide();
            } else {
              var startTip = '<span class="range-tip">'+params.startStr+'</span>';
              var endTip = '<span class="range-tip">'+params.endStr+'</span>';
              if (!params.startDate) {
                $(this).addClass("start-date");
                $(this).find(".gzl-calendar__ft").append(startTip);
                params.startDate = date;
              } else {
                if (new Date(date) < new Date(params.startDate)) {
                  calendar.rangeReset($(this),startTip);
                } else if (new Date(date) > new Date(params.startDate)) {
                  if (!params.endDate) {
                    var range = (new Date(date) - new Date(params.startDate))/1000/60/60/24+1;
                    if (params.maxRange) {
                      if (range > params.maxRange) {
                        console.log("最多选择"+params.maxRange+"天");
                      } else {
                        calendar.rangeSel($(this), range, endTip);
                      }
                    } else {
                      calendar.rangeSel($(this), range, endTip);
                    }
                  } else {
                    calendar.rangeReset($(this),startTip);
                  }
                }
              }
            }
          }
        })
      },
      rangeReset: function (e,tip) {// 范围重置
        params.calendar.find(".gzl-calendar__grid").removeClass("start-date").removeClass("end-date").removeClass("range-item");
        params.calendar.find(".range-tip").remove();
        e.addClass("start-date");
        e.find(".gzl-calendar__ft").append(tip);
        params.startDate = e.data("date");
        params.endDate = null;
      },
      rangeSel: function (e,days,tip) {// 范围选择
        e.removeClass("range-item").addClass("end-date");
        e.find(".gzl-calendar__ft").append(tip);
        params.endDate = e.data("date");
        params.calendar.find(".gzl-calendar__grid").each(function () {
          var gridDate = new Date($(this).data("date"));
          if(gridDate > new Date(params.startDate) && gridDate < new Date(params.endDate)){
            $(this).addClass("range-item");
          }
        });
        params.self.data({
          "start": params.startDate,
          "end": params.endDate
        }).removeClass("placeholder");
        params.self.find("[data-target="+params.startTarget+"]").text(params.startDate);
        params.self.find("[data-target="+params.endTarget+"]").text(params.endDate);
        params.gridClick({
          "start": params.startDate,
          "end": params.endDate,
          "days": days
        },params.self);
        calendar.hide();
      },
      hide: function () {
        if (params.type === "picked") {
          params.calendar.removeClass("show").transitionEnd(function () {
            this.remove();
          });
        }
      }
    };
    $.calendarHide = function () {
      $(".gzl-calendar_popup").removeClass("show").transitionEnd(function () {
        this.remove();
      });
    }
    // 获取一个月的天数
    function getMonthDateNumber(date) {
      var tem_date = new Date(date.getFullYear(), date.getMonth() + 1, 0);
      return tem_date.getDate();
    }
    // 格式化日期
    function dbDate(date) {
      date = date.toString();
      date = date.length === 1 ? "0" + date : date;
      return date;
    }
    calendar.init();
  }
})($);